#include "StdAfx.h"
#include "EditorConfig.h"
#include "ContainerHelper.h"
#include "Resource.h"

#define NODE_ROOT _T("AnyCAD")
#define NODE_CATALOG		_T("Catalog")
#define CATALOG_NAME		_T("name")
#define NODE_EDITOR			_T("Editor")
#define NODE_EDITOR_NAME		_T("Name")
#define NODE_EDITOR_GUID		_T("GUID")
#define NODE_EDITOR_TOOLTIP		_T("Tooltip")
#define NODE_EDITOR_ICON		_T("ICON")
#define NODE_EDITOR_PROP		_T("Property")


CEditorConfig::CEditorConfig(void)
{
	m_mapCatalogID[_T("Primitive")] = EC_PRIMIVE;
	m_mapCatalogID[_T("Sketch")] = EC_SKETCH;
	m_mapCatalogID[_T("Feature")] = EC_FEATURE;
	m_imageList.Create(16,16,TRUE | ILC_COLOR8,10,5);
}

CEditorConfig::~CEditorConfig(void)
{
	EditorCatalog::iterator it = m_Catalog.begin();
	for(; it!= m_Catalog.end(); ++it)
	{
		ClearPtrContainer<EditorList>(*(it->second));
		it->second = NULL;
	}

	m_Catalog.clear();
}

void CEditorConfig::VisitCatalog(EDITOR_CATALOG catalog, ICatalogVisitor* pVisitor)
{
	if(pVisitor == NULL)
		return;

	EditorCatalog::const_iterator it = m_Catalog.find(catalog);
	if(it == m_Catalog.end())
		return;

	EditorList* pList = it->second;
	EditorList::const_iterator itlist = pList->begin();
	for(; itlist!= pList->end(); ++itlist)
	{
		pVisitor->OnVisitItem(*itlist);
	}
}

bool CEditorConfig::Load(LPTSTR szPathFile)
{
	// parse xml document
	MSXML2::IXMLDOMDocumentPtr pXMLDoc;
	HRESULT hr = pXMLDoc.CreateInstance(__uuidof(MSXML2::DOMDocument60));
	if(!SUCCEEDED(hr))
	{
		AfxMessageBox(_T("Failed to load msxml6. \n\
			Please download it from www.caxsoft.com"));
		return false;
	}
	VARIANT_BOOL bOK = pXMLDoc->load(_variant_t(szPathFile));
	if(bOK == VARIANT_FALSE)
		return false;

	MSXML2::IXMLDOMElementPtr pRootNode = pXMLDoc->selectSingleNode(NODE_ROOT);
	if(NULL == pRootNode)
		return false;

	// parse property list from xml
	MSXML2::IXMLDOMNodeListPtr pNodeList;
	pNodeList = pRootNode->selectNodes(NODE_CATALOG);
	MSXML2::IXMLDOMNodePtr pNode;
	while(pNode=pNodeList->nextNode())
	{
		ParseCatalog(pNode);
	}

	return true;
}

bool CEditorConfig::ParseCatalog(const MSXML2::IXMLDOMNodePtr& pCatalogNode)
{
	MSXML2::IXMLDOMNamedNodeMapPtr pAttr = pCatalogNode->attributes;
	// get list name
	MSXML2::IXMLDOMNodePtr pAttrNode = pAttr->getNamedItem(CATALOG_NAME);
	CString szCatalogName = pAttrNode->text;
	CatalogIDMap::const_iterator it = m_mapCatalogID.find(szCatalogName);
	if(it == m_mapCatalogID.end())
		return false;

	// add a list to catalog
	EDITOR_CATALOG id = it->second;
	EditorCatalog::const_iterator itc = m_Catalog.begin();

	EditorList* pList = NULL;
	if(itc != m_Catalog.begin())
	{
		pList = itc->second;
	}
	else
	{
		pList = new EditorList();
		m_Catalog[id] =pList;
	}

	// parse the xml
	MSXML2::IXMLDOMNodeListPtr pItemList = pCatalogNode->selectNodes(NODE_EDITOR);
	MSXML2::IXMLDOMNodePtr pEditorNode;
	while(pEditorNode=pItemList->nextNode())
	{
		EditorItem* pItem = new EditorItem();
		pList->push_back(pItem);

		// get editor name
		MSXML2::IXMLDOMNodePtr pItemNode = NULL;
		pItemNode = pEditorNode->selectSingleNode(NODE_EDITOR_NAME);
		if(pItemNode)
			pItem->szName = (LPTSTR)pItemNode->text;
		
		// get editor guid
		pItemNode = pEditorNode->selectSingleNode(NODE_EDITOR_GUID);
		if(pItemNode)
			pItem->guid = (LPTSTR)pItemNode->text;

		// get editor tooltip
		pItemNode = pEditorNode->selectSingleNode(NODE_EDITOR_TOOLTIP);
		if(pItemNode)
			pItem->szToolTip = (LPTSTR)pItemNode->text;

		// get editor prop
		pItemNode = pEditorNode->selectSingleNode(NODE_EDITOR_PROP);
		if(pItemNode)
			pItem->szProperty = (LPTSTR)pItemNode->text;

		// get editor icon
		pItemNode = pEditorNode->selectSingleNode(NODE_EDITOR_ICON);
		if(pItemNode)
		{
			CString szIconPath = (LPTSTR)pItemNode->text;
	
			HBITMAP hBmp = (HBITMAP)LoadImage(NULL, szIconPath, IMAGE_BITMAP,
				0,0,LR_LOADFROMFILE|LR_LOADMAP3DCOLORS);
			if(hBmp)
			{	
				CBitmap bmp;
				bmp.Attach(hBmp);
				int id = m_imageList.Add(&bmp, RGB(192,192,192));
				if(id != -1)
				{
					pItem->hIcon = m_imageList.ExtractIcon(id);
				}
			}
			else
			{
				AfxMessageBox(_T("Failed to load ") + szIconPath);
			}
			// load the icon
		}
	}

	return true;
}